#include"HiKernel/HiFramework.h"
#include "HiModules/mHiLFSM/HiLFSM.h"
#include "HiModules/mHiLFSM/ScriptedStateMachine.h"
#include "HiModules/mHiLFSM/Entity.h"
#include "HiModules/mHiLFSM/Miner.h"

mHiLFSM::~mHiLFSM()
{
	delete m_pminer;
	lua_close(m_pLua);
}


void mHiLFSM::PostConfig()
{
	m_pLua = lua_open();

	//open the lua libaries - new in lua5.1
	luaL_openlibs(m_pLua);

	//open luabind
	open(m_pLua);

	RegisterEntityWithLua(m_pLua);
	RegisterScriptedStateMachineWithLua(m_pLua);
	RegisterMinerWithLua(m_pLua);

	RunLuaScript(m_pLua, "StateMachineScript.lua");

	m_pminer = new Miner("Bob");

	m_states = globals(m_pLua);

	if (type(m_states) == LUA_TTABLE)
		m_pminer->GetFSM()->SetCurrentState(m_states["State_GoHome"]);
}

void mHiLFSM::Update()
{
	m_pminer->Update();
	//Sleep(800);
}

bool mHiLFSM::HandleMessage(const Telegram& msg)
{
	luabind::object   CurrentState;

	//Lua.. OnMessage(msg)
	CurrentState = m_pminer->GetFSM()->CurrentState();
	CurrentState["OnMessage"](msg);

	return true;
}


void mHiLFSM::RegisterScriptedStateMachineWithLua(lua_State* pLua)
{
	module(pLua)
		[
			class_<ScriptedStateMachine<Miner> >("ScriptedStateMachine")

			.def("ChangeState", &ScriptedStateMachine<Miner>::ChangeState)
			.def("CurrentState", &ScriptedStateMachine<Miner>::CurrentState)
			.def("SetCurrentState", &ScriptedStateMachine<Miner>::SetCurrentState)
		];  
}


void mHiLFSM::RegisterEntityWithLua(lua_State* pLua)
{
	module(pLua)
		[
			class_<Entity>("Entity")

			.def("Name", &Entity::Name)
			.def("ID", &Entity::ID)   
		];  
}


void mHiLFSM::RegisterMinerWithLua(lua_State* pLua)
{
	module(pLua)
		[   
			class_<Miner, bases<Entity> >("Miner")

			.def("GoldCarried", &Miner::GoldCarried)
			.def("SetGoldCarried", &Miner::SetGoldCarried)
			.def("AddToGoldCarried", &Miner::AddToGoldCarried)
			.def("Fatigued", &Miner::Fatigued)
			.def("DecreaseFatigue", &Miner::DecreaseFatigue)
			.def("IncreaseFatigue", &Miner::IncreaseFatigue) 
			.def("GetFSM", &Miner::GetFSM)
		];  
}

extern "C" HI_DLLEXPORT
mHiLFSM* HiLoadModule_mHiLFSM(HiXmlNode* xml)
{
	mHiLFSM *m= new mHiLFSM(xml);
	return m;
}
